Another
issue that you face when administering SQL Server instances across an
organization is determining object dependencies between servers and
databases. If you have to make changes to objects in a database, it is
hard to establish a list of items that may be affected (especially if
the referencing objects are on another server). SQL Server 2008
introduces a new catalog view and two new dynamic management functions
that can be used to help determine object dependencies:
sys.sql_expression_dependencies: You can use the sys.sql_expression_dependencies
catalog view to report dependency information for a given database.
Cross-database entities are returned only when a valid four-part or
three-part name is specified.
sys.dm_sql_referenced_entities: You can use the sys.dm_sql_referenced_entities
dynamic management function to return one row for each user-defined
entity referenced by name in the definition of the specified
referencing entity. The result set is limited to the entities that are
referenced by the specified referencing entity.
sys.dm_sql_referencing_entities: You can use the sys.dm_sql_referencing_entities
dynamic management function to return one row for each user-defined
entity in the current database that references another user-defined
entity by name.
First, let's look at a couple
of queries that can help you determine object dependencies between SQL
Server instances. We have created a stored procedure called CrossServerSelect on the SQL Server 2008 instance named KEN-PC\SQL2K8 that references the Person.Address. table in the AdventureWorks database located on the default SQL Server instance named KEN-PC. The CrossServerSelect stored procedure executes a simple query using the four-part naming convention, as shown in Listing 1.
Example 1. CrossServerSelect Stored Procedure Definition
Create Procedure CrossServerSelect AS
Select Distinct City FROM [KEN-PC].AdventureWorks.Person.Address GO
|
Now we know there is an object
on the KEN-PC\SQL2K8 instance that references the KEN-PC instance.
Let's look at a couple of ways you can identify that dependency. One
way is to use the sys.sql_expression_dependencies catalog view, as shown in Listing 2.
This code should be executed from the context of the database that
contains the object that is doing the referencing. In this case, that
is the Test database on the KEN-PC\SQL2K8 instance. The results of Listing 2 can be seen in Figure 1.
Example 2. Returns All Referencing Dependencies in the Current Database
SELECT @@SERVERNAME LocalServer, OBJECT_NAME (referencing_id) referencing_object_name, referenced_server_name, referenced_database_name, referenced_schema_name, referenced_entity_name FROM sys.sql_expression_dependencies
|
Another
way to display cross-server dependencies is by using the
sys.dm_sql_referenced_entities dynamic management function, as shown in
Listing 3. You are required to provide the sys.dm_sql_referenced_entities
function with two parameters: the referencing entity name and the
referencing class. The object name we will be using is the
dbo.CrossServer-Select stored procedure
created earlier in this section. The referencing class can be one of
three types: OBJECT, DATABASE_DDL_TRIGGER, or SERVER_DDL_TRIGGER. In this case, we are using the OBJECT class. We are executing the code in Listing 7-3 against the Test database on the KEN-PC\SQL2K8 instance. The results of Listing 3 can be seen in Figure 2.
NOTE
You are required to provide the schema name along with the referencing entity name if you are using the OBJECT class.
Example 7.3. Returns Entities Referenced by the dbo.CrossServerSelect Object
SELECT @@SERVERNAME LocalServer, referenced_server_name, referenced_database_name, referenced_schema_name, referenced_entity_name FROM sys.dm_sql_referenced_entities ('dbo.CrossServerSelect','OBJECT')
|
Now
that you have seen how to display dependencies between servers, let's
look at an example using the sysjobshistory table in the msdb
database that doesn't require you to have multiple instances or any
special setup configurations. Let's start by taking a look at all of
the objects that reference the sysjobshistory table by running the code in Listing 4. The results of Listing 4 are shown in Figure 3.
Example 3. Returns Objects That Reference the sysjobshistory Table by Using the sys.sql_expression_dependencies Catalog View
USE msdb GO
SELECT OBJECT_NAME(referencing_id) AS referencing_entity_name, referenced_database_name AS database_name, referenced_schema_name, referenced_entity_name FROM sys.sql_expression_dependencies WHERE referenced_entity_name = 'sysjobhistory'
|
In this case you could also use the sys.dm_sql_referencing_entities function, as shown in Listing 5, since you are only returning referencing entities in the current database. The sys.dm_sql_referencing_entities
function does not have a column to display the referenced object or
database. There is no need to have a column for the referenced object,
since you are supplying the referenced object name as a parameter.
There is no referenced database column because the sys.dm_sql_referencing_entities function only returns dependencies for the current database. The results of Listing 5 are shown in Figure 4.
Example 5. Returns Objects That Reference the sysjobshistory Table by Using
the sys.dm_sql_referencing_entities Dynamic Management Function
USE msdb GO
SELECT referencing_entity_name FROM sys.dm_sql_referencing_entities ('dbo.sysjobhistory','OBJECT')
|
It is important to note that
the new functionality provided by dependency reporting will not catch
everything. You must use the proper three- or four-part notation when
referencing the object. Let look at an example using the sp_help_job function in the msdb database. If you run the code in Listing 6, you can see there are seven entities referenced by the sp_help_job procedure. The results can be viewed in Figure 5.
Example 6. Returns Entities Referenced by the sp_help_job Procedure
USE msdb GO
SELECT referenced_schema_name, referenced_entity_name, referenced_minor_name FROM sys.dm_sql_referenced_entities ('dbo.sp_help_job','OBJECT')
|
Now let's review a couple of lines in the sp_help_job stored procedure by executing sp_helptext 'sp_help_job'. If you look at the code block starting on line 238 (shown in Figure 6), you will see that sp_help_job executes the sp_get_composite_job_info stored procedure. If you refer to Figure 5, you will see that it is the first line in the result set.
Now look at line 142 of the code shown in Figure 7. You can see that the sp_help_job stored procedure is calling the sp_help_jobserver stored procedure using dynamic SQL. If you look back at the dependency results displayed in Figure 5, because sp_help_jobserver is called using dynamic SQL, it is not displayed as a dependency of the sp_help_job stored procedure.